package org.example.backend.service.impl;

import lombok.RequiredArgsConstructor;
import org.example.backend.dto.OpeningHoursDTO;
import org.example.backend.entity.OpeningHours;
import org.example.backend.exception.BusinessException;
import org.example.backend.repository.OpeningHoursRepository;
import org.example.backend.service.OpeningHoursService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

@Service
@RequiredArgsConstructor
public class OpeningHoursServiceImpl implements OpeningHoursService {

    private final OpeningHoursRepository openingHoursRepository;

    @Override
    @Transactional
    public OpeningHours createOpeningHours(OpeningHoursDTO openingHoursDTO) {
        if (openingHoursRepository.existsByDayOfWeek(openingHoursDTO.getDayOfWeek())) {
            throw new BusinessException("该日期的开放时间已存在");
        }

        validateOpeningHours(openingHoursDTO);

        OpeningHours openingHours = new OpeningHours();
        openingHours.setDayOfWeek(openingHoursDTO.getDayOfWeek());
        openingHours.setOpenTime(openingHoursDTO.getOpenTime());
        openingHours.setCloseTime(openingHoursDTO.getCloseTime());
        openingHours.setIsOpen(openingHoursDTO.getIsOpen() != null ? openingHoursDTO.getIsOpen() : true);

        return openingHoursRepository.save(openingHours);
    }

    @Override
    @Transactional
    public OpeningHours updateOpeningHours(Long id, OpeningHoursDTO openingHoursDTO) {
        OpeningHours openingHours = openingHoursRepository.findById(id)
                .orElseThrow(() -> new BusinessException("开放时间不存在"));

        if (!openingHours.getDayOfWeek().equals(openingHoursDTO.getDayOfWeek()) &&
                openingHoursRepository.existsByDayOfWeek(openingHoursDTO.getDayOfWeek())) {
            throw new BusinessException("该日期的开放时间已存在");
        }

        validateOpeningHours(openingHoursDTO);

        openingHours.setDayOfWeek(openingHoursDTO.getDayOfWeek());
        openingHours.setOpenTime(openingHoursDTO.getOpenTime());
        openingHours.setCloseTime(openingHoursDTO.getCloseTime());
        openingHours.setIsOpen(openingHoursDTO.getIsOpen());

        return openingHoursRepository.save(openingHours);
    }

    @Override
    @Transactional
    public void deleteOpeningHours(Long id) {
        if (!openingHoursRepository.existsById(id)) {
            throw new BusinessException("开放时间不存在");
        }
        openingHoursRepository.deleteById(id);
    }

    @Override
    public OpeningHours getOpeningHours(Long id) {
        return openingHoursRepository.findById(id)
                .orElseThrow(() -> new BusinessException("开放时间不存在"));
    }

    @Override
    public List<OpeningHours> getAllOpeningHours() {
        return openingHoursRepository.findAll();
    }

    @Override
    public OpeningHours getOpeningHoursByDay(DayOfWeek dayOfWeek) {
        return openingHoursRepository.findByDayOfWeek(dayOfWeek)
                .orElseThrow(() -> new BusinessException("该日期的开放时间不存在"));
    }

    @Override
    public boolean isOpenAt(LocalDateTime dateTime) {
        OpeningHours openingHours = openingHoursRepository.findByDayOfWeek(dateTime.getDayOfWeek())
                .orElse(null);

        if (openingHours == null || !openingHours.getIsOpen()) {
            return false;
        }

        LocalTime time = dateTime.toLocalTime();
        return !time.isBefore(openingHours.getOpenTime()) && 
               !time.isAfter(openingHours.getCloseTime());
    }

    private void validateOpeningHours(OpeningHoursDTO openingHoursDTO) {
        if (openingHoursDTO.getOpenTime().isAfter(openingHoursDTO.getCloseTime())) {
            throw new BusinessException("开放时间必须早于关闭时间");
        }
    }
} 